
class ResourceLock {

    // 用于存储当前持有锁的 Promise 对象
    #lockPromise = null
    // 用于释放当前持有锁函数
    #handler = null

    constructor() {}

    async acquire() {
        // 如果当前已经有其他 Promise 持有锁，则等待其释放
        while (this.#lockPromise) {
            await this.#lockPromise
        }
        // 创建一个新的 Promise ，用于持有锁
        this.#lockPromise = new Promise((resolve) => {
            this.#handler = resolve
        })
    }

    async release() {
        // 如果当前没有持有锁直接返回
        if (!this.#handler) {
            return
        }
        // 释放当前锁
        this.#handler()
        // 等待当前锁的 Promise 完成
        await this.#lockPromise
        // 重置锁的持有状态
        this.#lockPromise = null
    }

}

// TEST
async function main() {

    setTimeout(() => {
        console.log("setTimeout 5s...")
    }, 5000)

    const resourceLock = new ResourceLock()
    async function output(num) {
        await resourceLock.acquire()
        await new Promise((resolve) => {
            setTimeout(() => {
                resolve()
            }, 1000);
        })
        console.log(num + "s")
        await resourceLock.release()
    }

    for (let i = 1; i < 10; i++) {
        output(i)
    }
}
main()